package org.jeecg.modules.demo.ipds.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.demo.ipds.entity.*;
import org.jeecg.modules.demo.ipds.mapper.ByteFrameZuMapper;
import org.jeecg.modules.demo.ipds.mapper.IpTreeMapper;
import org.jeecg.modules.demo.ipds.mapper.MyIpWrodMapper;
import org.jeecg.modules.demo.ipds.service.*;
import org.jeecg.modules.demo.util.FreemarkerUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 我的协议文档
 * @Author: jeecg-boot
 * @Date:   2024-01-29
 * @Version: V1.0
 */
@Slf4j
@Service
public class MyIpWrodServiceImpl extends ServiceImpl<MyIpWrodMapper, MyIpWrod> implements IMyIpWrodService {

    @Autowired
    private IpTreeMapper ipTreeMapper;

    @Autowired
    private IIpTreeService ipTreeService;

    @Autowired
    private ITreeByteListService treeByteListService;

    @Autowired
    private ITreeByteListService2 treeByteListService2;

    @Autowired
    private ByteFrameZuMapper byteFrameZuMapper;
    @Autowired
    private IBitListService bitListService;

    @Override
    public void updateBatchByIDsetDeleted(List<String> ids) {
        UpdateWrapper<MyIpWrod> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("id", ids);
//        this.baseMapper.update;
    }


    /**
     * 生成Id映射Map
     *
     * @param treeA 原树节点集合
     * @return 原树和新树Id映射Map
     */
    private static Map<String, String> getOldNewMap(List<IpTree> treeA) {
        // 所有节点id集合
        List<String> nodeIdList = treeA.stream().map(IpTree::getId).collect(Collectors.toList());
        // 获取原树的跟节点id
        String rootId = treeA.stream().filter(item -> item.getPid().equals("0"))
                .collect(Collectors.toList())
                .get(0).getId();
        // 新树跟节点newId期前指定
        // 根据实际情况调整
        String newId = "b1";
        Map<String, String> idMap = new HashMap<>(treeA.size());
        for (String nodeId : nodeIdList) {
            // 先找到根节点，（根节点的nodePid都是 -1）
            if (nodeId.equals(rootId)) {
                idMap.put(rootId, newId);
            } else {
                // 用 UUID 生成 新树和旧树的id映射关系
                // 根据实际id策略生成，为了方便此处使用UUID
                idMap.put(nodeId, UUID.randomUUID().toString());
            }
        }
        return idMap;
    }


    /**
     * 生成复制后的树结构
     *
     * @param treeA 原树节点集合
     * @param idMap 原树和新树Id映射Map，由 step1 生成
     * @return 改变id的树节点集合
     */
    private static List<IpTree> getTreeB(List<IpTree> treeA, Map<String, String> idMap) {
        List<IpTree> treeB = new ArrayList<>(treeA.size());
        for (IpTree IpTree : treeA) {
            String id = idMap.get(IpTree.getId());
            // 可不判空，适用于根节点标记不是 nodePid
            if (null != id) {
                IpTree.setId(id);
            }
            String pid = idMap.get(IpTree.getPid());
            // 跟节点标记在父ID，即 nodePid = -1
            // 跟节点的标志 nodePid = -1 不在映射中时不用重新复制，在 idMap 中也取不到，不用处理
            if (null != pid) {
                IpTree.setPid(pid);
            }
            treeB.add(IpTree);
        }
        return treeB;
    }


    public void parseTree(List<IpTree> treeA, String wordId) {
        for (IpTree ipTree : treeA) {
            if (ipTree.getPid().equals("0")) {

                String ipTreeId = ipTree.getId(); //原树id
                ipTree.setWordId(wordId);
                ipTree.setCreateBy(null);
                ipTree.setCreateTime(null);
                ipTree.setId(null);
//                System.out.println(ipTree);
                ipTreeMapper.insert(ipTree);
                //下级需改的pid
                String newIpTreeId = ipTree.getId();
                if (ipTree.getType().equals("协议")) {
                    System.out.println("是协议");
                    saveByteAndBit(ipTree, ipTreeId, newIpTreeId);
                    continue;
                }
                tree(ipTreeId, newIpTreeId, wordId);

            }
        }
    }


    public void tree(String pid, String newIpTreeId, String wordId) {
        QueryWrapper<IpTree> ipTreeqw = new QueryWrapper<>();
        ipTreeqw.eq("pid", pid);
        List<IpTree> ipTrees = ipTreeMapper.selectList(ipTreeqw);


        if (ipTrees.size() > 0) {
            for (IpTree ipTree : ipTrees) {
                //原id
                String ipTreeId = ipTree.getId();
                ipTree.setId(null);
                ipTree.setWordId(wordId);
                ipTree.setPid(newIpTreeId);
                ipTree.setCreateBy(null);
                ipTree.setCreateTime(null);
                ipTreeMapper.insert(ipTree);
                //下级需改的pid
                String newIpTreeId2 = ipTree.getId();
                if (ipTree.getType().equals("协议")) {
                    System.out.println("是协议");
                    saveByteAndBit(ipTree, ipTreeId, newIpTreeId2);
                    return;
                }

                tree(ipTreeId, newIpTreeId2, wordId);

            }
        }


    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void templateAdd(String id) {

        MyIpWrod myIpWrod = this.baseMapper.selectById(id);
        myIpWrod.setCreateTime(null);
        myIpWrod.setId(null);
        myIpWrod.setIsMode("false");
        this.baseMapper.insert(myIpWrod);


        QueryWrapper<IpTree> ipTreeqw = new QueryWrapper<>();
        ipTreeqw.eq("word_id", id);
        ipTreeqw.eq("pid", "0");
        List<IpTree> ipTrees = ipTreeMapper.selectList(ipTreeqw);
        parseTree(ipTrees, myIpWrod.getId());



    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeAndChild(String id) {

        QueryWrapper<IpTree> ipTreeQueryWrapper = new QueryWrapper<>();
        ipTreeQueryWrapper.eq("word_id",id);
        List<IpTree> ipTrees = ipTreeMapper.selectList(ipTreeQueryWrapper);
        for (IpTree ipTree : ipTrees) {
            if (!ipTree.getType().equals("章节")){
                //删除字节
                String ipTreeId = ipTree.getId();
                QueryWrapper<TreeByteList> treequeryWrapper = new QueryWrapper<>();
                treequeryWrapper.eq("ip_tree_id", ipTreeId);
                List<TreeByteList> list = treeByteListService.list(treequeryWrapper);
                //删除子帧
                for (TreeByteList treeByteList : list) {
                    QueryWrapper<ByteFrameZu> byteFrameZuQueryWrapper = new QueryWrapper<>();
                    byteFrameZuQueryWrapper.eq("byte_id",treeByteList.getId());
                    List<ByteFrameZu> byteFrameZus = byteFrameZuMapper.selectList(byteFrameZuQueryWrapper);
                    if (byteFrameZus!=null){
                        for (ByteFrameZu frameZus : byteFrameZus) {
                            //删除子帧字节
                            String frameZusId  = frameZus.getId();
                            QueryWrapper<TreeByteList2> queryWrapper2 = new QueryWrapper<>();
                            queryWrapper2.eq("pid", frameZusId);
                            List<TreeByteList2> list2 = treeByteListService2.list(queryWrapper2);
                            for (TreeByteList2 treeByteList2 : list2) {
                                //删除子帧位
                                String zzByteId = treeByteList2.getId();
                                QueryWrapper<BitList> zzBitqw = new QueryWrapper<>();
                                zzBitqw.eq("byte_id",zzByteId);
                                bitListService.remove(zzBitqw);
                            }
                            treeByteListService2.remove(queryWrapper2);


                        }
                    }


                    QueryWrapper<BitList> bitListQueryWrapper = new QueryWrapper<>();
                    bitListQueryWrapper.eq("byte_id",treeByteList.getId());
                    List<BitList> list1 = bitListService.list(bitListQueryWrapper);
                    if (list1!=null){
                        bitListService.remove(bitListQueryWrapper);
                    }


                }
                treeByteListService.remove(treequeryWrapper);



            }
        }
        ipTreeMapper.delete(ipTreeQueryWrapper);
        this.baseMapper.deleteById(id);
    }


    //    如果是协议 会有字节与位需要新增
    private void saveByteAndBit(IpTree ipTree, String ipTreeId, String newIpTreeId2) {
        if (ipTree.getType().equals("协议")) {
            System.out.println("生成字节");
            QueryWrapper<TreeByteList> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("ip_tree_id", ipTreeId);
            //这里是此协议的字节集合
            List<TreeByteList> treeByte = treeByteListService.list(queryWrapper);
            //去除ID和修改父树ID
            for (TreeByteList treeByteList : treeByte) {
                //---------------------字节生成开始----------------------
                //先把原来的字节Id拿出来用来查原来有哪些位和子帧
                String byte_id = treeByteList.getId();
                treeByteList.setId(null);
                treeByteList.setIsSymbolString(treeByteList.getIsSymbolString());
                treeByteList.setIpTreeId(newIpTreeId2);
                //这需要一个新增的操作才能产生一个ID
                System.out.println("生成一个字节"+treeByteList);
                treeByteListService.save(treeByteList);
                String newByteId = treeByteList.getId();
                //---------------------字节生成结束----------------------

                //---------------------子帧生成开始----------------------
                QueryWrapper<ByteFrameZu> byteFrameZuQueryWrapper = new QueryWrapper<>();
                byteFrameZuQueryWrapper.eq("byte_id",byte_id);
                byteFrameZuQueryWrapper.orderByAsc("index_sx");
                List<ByteFrameZu> byteFrameZus = byteFrameZuMapper.selectList(byteFrameZuQueryWrapper);
                //判断子帧
                if (!byteFrameZus.isEmpty()&&byteFrameZus.size()>0){
                    System.out.println(byteFrameZus);
                    //新增子帧
                    for (ByteFrameZu frameZus : byteFrameZus) {
                        //先把子帧组id拿出来
                        String zu_id = frameZus.getId();
                        frameZus.setId(null);
                        frameZus.setByteId(newByteId);
                        frameZus.setIpTreeId(newIpTreeId2);
                        byteFrameZuMapper.insert(frameZus);
                        System.out.println("生成一个子帧组"+frameZus);
                        //------------------子帧字节开始新增----------
                        QueryWrapper<TreeByteList2> queryWrapper2 = new QueryWrapper<>();
                        queryWrapper2.eq("pid", zu_id);
                        //查询组id有多少字节
                        List<TreeByteList2> treeByteList2s = treeByteListService2.list(queryWrapper2);
                        if (treeByteList2s!=null&&treeByteList2s.size()>0) {
                            for (TreeByteList2 treeByteList2 : treeByteList2s) {
                                //子帧字节新id
                                String byteId2 = treeByteList2.getId();
                                treeByteList2.setId(null);
                                treeByteList2.setCreateTime(null);
                                treeByteList2.setPid(frameZus.getId());
                                treeByteList2.setIpTreeId(newIpTreeId2);
                                treeByteListService2.save(treeByteList2);
                                System.out.println("生成一个子帧字节"+treeByteList2);
                                //------------------子帧字节结束新增----------

                                //---------------------子帧位新增开始----------------------
                                QueryWrapper<BitList> bitListQueryWrapper2 = new QueryWrapper<>();
                                bitListQueryWrapper2.eq("byte_id", byteId2);
                                List<BitList> bitLists2 = bitListService.list(bitListQueryWrapper2);
                                //位集合
                                if (bitLists2!=null&&bitLists2.size()>0) {

                                    for (BitList bitList : bitLists2) {
                                        bitList.setId(null);
                                        //修改属性
                                        bitList.setByteId(treeByteList2.getId());
                                        bitList.setIpTreeId(newIpTreeId2);
                                        System.out.println("生成一个子帧位" + bitList);
                                        bitListService.save(bitList);
                                    }
                                }
                                //---------------------子帧位新增结束----------------------
                            }
                            //------------------子帧字节结束新增----------
                        }
                    }
                }



                //---------------------位生成开始----------------------
                QueryWrapper<BitList> bitListQueryWrapper = new QueryWrapper<>();
                bitListQueryWrapper.eq("byte_id", byte_id);
                //位集合
                List<BitList> bitLists = bitListService.list(bitListQueryWrapper);
                if (bitLists.size() > 0){
                    for (BitList bitList : bitLists) {
                        bitList.setId(null);
                        //修改属性
                        bitList.setByteId(newByteId);

                        bitList.setIpTreeId(newIpTreeId2);
                        System.out.println("生成一个位"+bitList);
//                    bitListService.save(bitList);
                    }
                }


            }
        }
    }



    public  void createXml(String wordId){
        MyIpWrod IpWord = this.baseMapper.selectById(wordId);
        String ipName = IpWord.getIpName();
        try {
            // 创建解析器工厂
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = factory.newDocumentBuilder();
            Document document = db.newDocument();
            // 不显示standalone="no"
            document.setXmlStandalone(true);
            // 创建文档
            Element bookstore = document.createElement("File");
            // 协议文档名
            bookstore.setAttribute("Name",ipName);
            QueryWrapper<IpTree> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("word_id", wordId);
            queryWrapper.eq("type","协议");
            List<IpTree> list = ipTreeService.list(queryWrapper);

            for (IpTree ipTree : list) {
                String sectionName = ipTree.getSectionName();
                String ipTreeId = ipTree.getId();
                // 创建协议
                Element Protocol = document.createElement("Protocol");
                //协议名
                Protocol.setAttribute("Name", sectionName);
                Protocol.setAttribute("ID", ipTreeId);
                Protocol.setAttribute("HeadSize", "协议字节量");
                Protocol.setAttribute("HeadValue", "协议字节值");


                QueryWrapper<TreeByteList> treeByteListQueryWrapper = new QueryWrapper<>();
                treeByteListQueryWrapper.eq("ip_tree_id",ipTreeId);
                List<TreeByteList> treeByte = treeByteListService.list(treeByteListQueryWrapper);
                //创建字节
                for (TreeByteList treeByteList : treeByte) {
                    String ByteId = treeByteList.getId();
                    Element ByteItem = document.createElement("ByteItem");
                    ByteItem.setAttribute("ID", ipTreeId);
                    ByteItem.setAttribute("HeadSize", "协议字节量");
                    ByteItem.setAttribute("HeadValue", "协议字节值");
                    Protocol.appendChild(ByteItem);
                }

//                    为book节点添加属性
//                    把字节添加进去
                bookstore.appendChild(Protocol);
//                     将bookstore节点（已包含book）添加到dom树中

            }
            document.appendChild(bookstore);



            // 创建TransformerFactory对象
            TransformerFactory tff = TransformerFactory.newInstance();
            // 创建 Transformer对象
            Transformer tf = tff.newTransformer();

            // 输出内容是否使用换行
            tf.setOutputProperty(OutputKeys.INDENT, "yes");
            // 创建xml文件并写入内容
            tf.transform(new DOMSource(document), new StreamResult(new File("book1.xml")));
            System.out.println("生成book1.xml成功");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("生成book1.xml失败");
        }
    }


    /**
     * @param request
     * @param response
     * @param id
     * @description: word文档模板导出
     * @return: void
     * @author: zhang
     * @date: 2024/3/30 10:57
     */
    @Override
    public String exportWord(HttpServletRequest request, HttpServletResponse response, Long id) throws JeecgBootException {
        // 1、查询、构建导出数据
        Map<String, Object> data = new HashMap<>();
        MyIpWrod myIpWrod = baseMapper.selectById(id);
        if (ObjectUtils.isEmpty(myIpWrod)){
            throw new JeecgBootException("协议Id不存在！");
        }
        // 获取树状态章节协议树
        List<IpTree> ipTreeList = new LambdaQueryChainWrapper<>(ipTreeService.getBaseMapper())
                .eq(IpTree::getWordId, myIpWrod.getId())
                .list();
        if (ObjectUtils.isEmpty(ipTreeList)){
            throw new JeecgBootException("章节/协议不存在！");
        }


        List<IpTree> parentIpTree = ipTreeList.stream().filter(f -> f.getPid().equals("0")).collect(Collectors.toList());
        List<IpTree> childenIpTree = ipTreeList.stream().filter(f -> !f.getPid().equals("0")).collect(Collectors.toList());
        // 构建章节、协议树
        for (IpTree ipTree : parentIpTree) {
            List<IpTree> children = this.getIpTreeChildren(childenIpTree, ipTree.getId());
            ipTree.setChildren(children);
        }
        // 拆解树
        List<Object> listMap = new ArrayList<>();

        int tableIndex = 0;
        for (int i = 0; i < parentIpTree.size(); i++) {
            IpTree parent = parentIpTree.get(i);
            Map<String, Object> dataMap = new HashMap<>();

            List<Object> sectionList = new ArrayList<>();
            List<Map<String, Object>> byteList = new ArrayList<>();
            List<Map<String, Object>> subframeList = new ArrayList<>();
            List<Map<String, Object>> bitList = new ArrayList<>();
            // 判断根节点类型
            if (IpTree.IpTreeTypeEnum.SECTION.getName().equals(parent.getType())) {
                // 章节数据收集
                List<IpTree> list = this.getIpTreeChildrens(parent);
                double sectionIndex = i * 10;
                String pid = StringUtils.EMPTY;
                if (ObjectUtils.isNotEmpty(list)){
                    for (IpTree tree : list) {
                        if (IpTree.IpTreeTypeEnum.SECTION.getName().equals(tree.getType())) {
                            dataMap.put("name", parent.getSectionName());
                            Map<String, Object> map = new HashMap<>();
                            // 根据pid判断深度是否发生变化
                            if (!pid.equals(tree.getPid())){
                                pid = tree.getId();
                                sectionIndex+=10;
                            }else {
                                sectionIndex += 1;
                            }
                            map.put("index", sectionIndex / 10);
                            map.put("type", tree.getType());
                            map.put("sectionName", tree.getSectionName());
                            map.put("message", tree.getMessage());
                            sectionList.add(map);
                        }
                        else if (IpTree.IpTreeTypeEnum.AGREEMENT.getName().equals(tree.getType())){
                            parentIpTree.add(i+1,tree);

                        }

                    }
                }
            }




            else if (IpTree.IpTreeTypeEnum.AGREEMENT.getName().equals(parent.getType())){

                dataMap.put("name", parent.getSectionName());
                // 查询树下所有的字节
                List<BitList> allBitList = new LambdaQueryChainWrapper<>(bitListService.getBaseMapper()).eq(BitList::getIpTreeId, parent.getId()).list();
                Map<String, List<BitList>> bitListMap = allBitList.stream().collect(Collectors.groupingBy(BitList::getByteId));
                // 查询字节数据
                List<TreeByteList> childenByteList = new LambdaQueryChainWrapper<>(treeByteListService.getBaseMapper()).eq(TreeByteList::getIpTreeId, parent.getId()).orderByAsc(TreeByteList::getIndexSx).list();
                if (ObjectUtils.isNotEmpty(childenByteList)){
                    for (TreeByteList item : childenByteList) {
                        Map<String, Object> map = new HashMap<>();
                        map.put("id", item.getId());
                        map.put("byteName", item.getByteName());
                        map.put("sn", item.getSn());
                        map.put("resolutionRatio", item.getResolutionRatio());
                        map.put("dataType", item.getDataType());
                        map.put("fieldLength", item.getFieldLength());
                        map.put("defaultValue", item.getDefaultValue());
                        map.put("annotation", item.getAnnotation());
                        byteList.add(map);
                    }
                    tableIndex++;
                    dataMap.put("tableIndex", tableIndex);
                    // 收集字节下的位
                    for (TreeByteList treeByte : childenByteList) {
                        if(bitListMap.containsKey(treeByte.getId())){
                            List<BitList> bitLists = bitListMap.get(treeByte.getId());
                            List<Map<String, Object>> list = this.getBitExportInfo(bitLists);
                            Map<String, Object> map = new HashMap<>();
                            map.put("bitList", list);
                            map.put("name", treeByte.getByteName());
                            map.put("parentType", "01");
                            map.put("parentId", treeByte.getId());
                            bitList.add(map);
                        }
                    }
                }
                // 查询子帧数据
                List<ByteFrameZu> childenByteFrameZuList = new LambdaQueryChainWrapper<>(byteFrameZuMapper).eq(ByteFrameZu::getIpTreeId, parent.getId()).orderByAsc(ByteFrameZu::getIndexSx).list();
                if(ObjectUtils.isNotEmpty(childenByteFrameZuList)){
                    List<String> byteFrameZuByteIdList = childenByteFrameZuList.stream().map(ByteFrameZu::getId).collect(Collectors.toList());
                    List<TreeByteList2> byteFrameZuByteList = new LambdaQueryChainWrapper<>(treeByteListService2.getBaseMapper()).in(TreeByteList2::getPid, byteFrameZuByteIdList).orderByAsc(TreeByteList2::getIndexSx).list();
                    if (ObjectUtils.isNotEmpty(byteFrameZuByteList)){
                        Map<String, List<TreeByteList2>> byteList2PidMap = byteFrameZuByteList.stream().collect(Collectors.groupingBy(TreeByteList2::getPid));
                        for (ByteFrameZu byteFrameZu : childenByteFrameZuList) {
                            if (byteList2PidMap.containsKey(byteFrameZu.getId())){
                                // 收集子帧字节信息
                                List<TreeByteList2> treeByteList2List = byteList2PidMap.get(byteFrameZu.getId());
                                List<Map<String, Object>> list = treeByteList2List.stream().map(m -> {
                                    Map<String, Object> map = new HashMap<>();
                                    map.put("id", m.getId());
                                    map.put("byteName", m.getByteName());
                                    map.put("sn", m.getSn());
                                    map.put("resolutionRatio", m.getResolutionRatio());
                                    map.put("dataType", m.getDataType());
                                    map.put("fieldLength", m.getFieldLength());
                                    map.put("defaultValue", m.getDefaultValue());
                                    map.put("annotation", m.getAnnotation());
                                    return map;
                                }).collect(Collectors.toList());
                                tableIndex++;
                                Map<String, Object> map = new HashMap<>();
                                map.put("byteList", list);
                                map.put("tableIndex", tableIndex);
                                map.put("name", byteFrameZu.getName());
                                map.put("byteId", byteFrameZu.getByteId());
                                subframeList.add(map);
                                // 关联父表
                                byteList.forEach(bytee -> {
                                    if (byteFrameZu.getByteId().equals(bytee.get("id"))) {
                                        bytee.put("description", "详见表".concat(map.get("tableIndex").toString()));
                                    }
                                });
                                // 收集子帧字节下的位
                                for (TreeByteList2 treeByte : treeByteList2List) {
                                    if(bitListMap.containsKey(treeByte.getId())){
                                        List<BitList> bitLists = bitListMap.get(treeByte.getId());
                                        List<Map<String, Object>> bitMapList = this.getBitExportInfo(bitLists);
                                        Map<String, Object> bitMap = new HashMap<>();
                                        bitMap.put("bitList", bitMapList);
                                        bitMap.put("name", treeByte.getByteName());
                                        bitMap.put("parentType", "02");
                                        bitMap.put("parentId", treeByte.getId());
                                        bitList.add(bitMap);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            // 关联位表详细描述
            if (ObjectUtils.isNotEmpty(bitList)){
                for (int j = 0; j < bitList.size(); j++) {
                    Map<String, Object> item = bitList.get(j);
                    tableIndex++;
                    item.put("tableIndex", tableIndex);
                    // 关联父表
                    if (item.get("parentType").equals("01")) {
                        byteList.forEach(bytee->{
                            if (item.get("parentId").equals(bytee.get("id"))){
                                bytee.put("description", "详见表".concat(item.get("tableIndex").toString()));
                            }
                        });
                    }else if (item.get("parentType").equals("02")){
                        subframeList.forEach(subframe->{
                            if (subframe.containsKey("byteList")){
                                List<Map<String,Object>> list = (List)subframe.get("byteList");
                                list.forEach(bytee->{
                                    if (item.get("parentId").equals(bytee.get("id"))){
                                        bytee.put("description", "详见表".concat(item.get("tableIndex").toString()));
                                    }
                                });
                            }
                        });
                    }
                }
            }
            dataMap.put("type", parent.getType());
            // dataMap.put("name", "xxx");
            dataMap.put("sectionList", sectionList);
            dataMap.put("byteList", byteList);
            dataMap.put("subframeList", subframeList);
            dataMap.put("bitList", bitList);



            listMap.add(dataMap);


        }

        // --------- 构建协议文档基本信息 ---------
        data.put("ipName",myIpWrod.getIpName());
        data.put("ipType",myIpWrod.getIpType());
        data.put("wordCode",myIpWrod.getWordCode());
        data.put("securityLevel",myIpWrod.getSecurityLevel());
        data.put("stage",myIpWrod.getStage());
        // --------- 构建章节协议信息 ---------
        data.put("list", listMap);


//        return null;

        // 3、导出文档
        String ipName = myIpWrod.getIpName();
        String fileName = ipName+"协议文档.doc";
        String templateName = "IpWordExportTemplate.ftl";

        return FreemarkerUtils.generateWord(templateName, fileName, data, request, response);
    }



    /**
     * @description: 组装bit导出数据
     * @param bitLists
     * @return: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     * @author: zhang
     * @date: 2024/3/31 16:51
     */
    public List<Map<String, Object>> getBitExportInfo(List<BitList> bitLists){
        if (ObjectUtils.isEmpty(bitLists)){
            return null;
        }
        return bitLists.stream().map(m -> {
            Map<String, Object> map = new HashMap<>();
            map.put("indexSx", m.getIndexSx());
            map.put("bitName", m.getBitName());
            map.put("startBit", m.getStartBit());
            map.put("endBit", m.getEndBit());
            map.put("bitLength", m.getBitLength());
            map.put("resolutionRatio", m.getResolutionRatio());
            map.put("annotation", m.getAnnotation());
            return map;
        }).collect(Collectors.toList());

    }

    /**
     * @description: 获取对象children内的所有数据
     * @param parent
     * @return: java.util.List<org.jeecg.modules.demo.ipds.entity.IpTree>
     * @author: zhang
     * @date: 2024/3/30 13:50
     */
    private List<IpTree> getIpTreeChildrens(IpTree parent){
        List<IpTree> list = new ArrayList<>();
        list.add(parent);
        List<IpTree> childrenList = parent.getChildren();
        if (ObjectUtils.isEmpty(childrenList)) {
            return list;
        }
        for (IpTree ipTree : childrenList) {
            List<IpTree> childrens = this.getIpTreeChildrens(ipTree);
            // 这里以增加协议章节的排序
            list.addAll(childrens);
        }
        return list;
    }

    /**
     * @description: 递归获取IpTree子集
     * @param list
     * @param parentId
     * @return: java.util.List<org.jeecg.modules.demo.ipds.entity.IpTree>
     * @author: zhang
     * @date: 2024/3/30 23:20
     */
    private List<IpTree> getIpTreeChildren(List<IpTree> list, String parentId) {
        if (ObjectUtils.isEmpty(list)) {
            return null;
        }
        List<IpTree> children = list.stream().filter(f -> parentId.equals(f.getPid())).collect(Collectors.toList());
        if (ObjectUtils.isNotEmpty(children)){
            for (IpTree child : children) {
                List<IpTree> ipTreeChildren = this.getIpTreeChildren(list, child.getId());
                child.setChildren(ipTreeChildren);
            }
        }
        return children;
    }


}
